package com.jbp.service;

import com.jbp.domin.LuckUser;
import com.jbp.exception.RRException;
import com.jbp.model.Gift;
import com.jbp.model.GiftLot;
import com.jbp.service.impl.UserPropertyServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;

/**
 * 飞马 2块奖池 1：10
 */
@Service
public class LuckyUtil102 {
    //每次抽消耗奖金币
    public static final int price = 20;
    @Autowired
    private LuckyUtil101 luckyUtilSmall;
    @Autowired
    private UserPropertyServiceImpl userPropertyServiceImpl;
    @Autowired
    private LuckyUtil luckyUtil;
    /**
     * patch 补礼物  0表示不补
     * */
    public List<Gift> luck(Integer userId, int times, List<GiftLot> list, int patch, Integer roomId) {
        LuckUser luckUser = luckyUtil.getLuckUser(userId, price);
        int pay = luckUser.getPay();
        int income = luckUser.getIncome();


        if (pay+times*price<10000) {
            return luckyUtilSmall.luck(userId, times, list, 0, roomId);
        } else {
            int biggest = 500000;
            int maxGift = userPropertyServiceImpl.getMaxGift(userId);
            if (maxGift!=0) {
                biggest = maxGift;
            }

            List<Gift> result = new ArrayList<>();
            for (int i = 0; i < times; i++) {
                pay += price;

                int luck = luck(pay, income, patch, biggest);
                if (luck>1000) {
                    patch++;
                }
                //将奖品转化为礼物
                Gift gift = null;
                for (GiftLot giftLot : list) {
                    if (giftLot.getGift().getCoin() == luck) {
                        gift = giftLot.getGift();
                        break;
                    }
                }

                if (gift == null) {
                    throw new RRException("网络错误");
                }

                income += gift.getCoin();
                result.add(gift);
            }

            System.out.println("大  pay="+pay+" in="+income);

            luckUser.setPay(pay);
            luckUser.setIncome(income);
            luckyUtil.updateLuckUser(luckUser);

            luckyUtil.addPatch((int) (times * 0.02d * price));
            return result;
        }
    }

    Pool poolA = new Pool();
    Pool poolB = new Pool();
    Pool poolC = new Pool();
    Pool poolD = new Pool();
    Pool poolE = new Pool();

    @SuppressWarnings("AliControlFlowStatementWithoutBraces")
    void luckTest(UserLuck userLuck, Map <Integer, Integer> out) {
        if (userLuck.totalPay<10000) {
            new LuckyUtil15().luckTest(userLuck, out);
        } else {
            Pool pl;
            if (userLuck.totalPay<100000) {
                pl = poolB;
            } else if (userLuck.totalPay<500000) {
                pl = poolC;
            }  else if (userLuck.totalPay<2000000) {
                pl = poolD;
            }else {
                pl = poolE;
            }

            userLuck.pay += price;
            userLuck.totalPay += price;
            userLuck.currPay += price;
            pl.allPay += price;

            int luck = luck(userLuck.pay, userLuck.income, 0,  500000);

            userLuck.income += luck;
            userLuck.totalIncome += luck;
            userLuck.currIncome += luck;
            pl.allIncome += luck;

            if (out.containsKey(luck)) {
                out.put(luck, out.get(luck) + 1);
            } else {
                out.put(luck, 1);
            }
        }
    }

    private int luck(int pay, int income, int patch, int biggest) {
        LinkedHashMap<Integer, Integer> config;
        /*if (pay<10000) {
            config = getGiftCoinfigA();
        } else */if (pay<100000) {
            config = getGiftCoinfigB();
        } else if (pay<500000) {
            config = getGiftCoinfigC();
        } else if (pay<1500000) {
            config = getGiftCoinfigD();
        } else {
            config = getGiftCoinfigE();
        }
        int min=0;

        int maxWin;
        if (pay<150000) {
            maxWin = 35000;
        } else if (pay<500000) {
            maxWin = 20000;
        } else if (pay<1200000) {
            maxWin = 15000;
        } else {
            maxWin = (int) (pay*(1.195-1.175));
        }

        biggest = Math.min(Math.max((int)(pay*1.177+maxWin-income), 15000), biggest);

        if (patch<1) {
            double pRate = 0;
            if (pay > 200000) {
                pRate = 1.018;
            } else if (pay > 160000) {
                pRate = 1.004;
            } else if (pay > 140000) {
                pRate = 0.97;
            } else if (pay > 95000) {
                pRate = 0.7;
            }/* else if (pay > 50000) {
                pRate = 0.6;
            } else if (pay > 8000) {
                pRate = 0.55;
            }*/

            if (pRate > 0 && pay * pRate > income) {
                if (pay > 500000) {
                    biggest = Math.min(biggest, 30000);
                    min = 5000;
                } else if (pay > 250000) {
                    biggest = Math.min(biggest, 20000);
                    min = 1000;
                } else if (pay > 100000) {
                    biggest = Math.min(biggest, 15000);
                    min = 500;
                } else {
                    biggest = Math.min(biggest, 6000);
                    min = 100;
                }

            }

            min=Math.min(min, 20000);
            min = Math.min(min, biggest);

//            if (min!=0) {
//                System.out.println(min);
//            }
        }
        int luck = LuckyUtil.luckRandom(config, min, biggest);
        /*if (min>0) {
            System.out.println("补 "+luck);
        }*/
        return luck;
    }
    /**
     * A奖池 投入1w钻以内
     */
    private static LinkedHashMap<Integer, Integer> getGiftCoinfigA() {
        LinkedHashMap<Integer, Integer> map = new LinkedHashMap<>();
        map.put(1, 33651);
        map.put(10, 8000);
        map.put(30, 2800);
        map.put(52, 550);
        map.put(199, 250);
        map.put(520, 350);
        map.put(999, 140);
        map.put(1111, 80);
        map.put(1999, 55);
        map.put(3344, 40);
        map.put(5200, 20);
        map.put(8888, 2);
        map.put(11111, 1);
        return map;
    }
    /**
     * B奖池 投入10w钻以内
     */
    private static LinkedHashMap<Integer, Integer> getGiftCoinfigB() {
        LinkedHashMap<Integer, Integer> map = new LinkedHashMap<>();
        map.put(1, 39991);
        map.put(10, 5000);
        map.put(30, 1000);
        map.put(52, 300);
        map.put(199, 200);
        map.put(520, 250);
        map.put(999, 83);
        map.put(1111, 68);
        map.put(1999, 54);
        map.put(3344, 42);
        map.put(5200, 27);
        map.put(8888, 9);
        map.put(11111, 2);
        map.put(33333, 1);
        return map;
    }
    /**
     * C奖池 投入50w钻以下
     */
    private static LinkedHashMap<Integer, Integer> getGiftCoinfigC() {
        LinkedHashMap<Integer, Integer> map = new LinkedHashMap<>();
        map.put(1, 43000*2);
        map.put(10, 5000*2);
        map.put(30, 500*2);
        map.put(52, 200*2);
        map.put(199, 200*2);
        map.put(520, 150*2);
        map.put(999, 88*2);
        map.put(1111, 50*2);
        map.put(1999, 45*2);
        map.put(3344, 33*2);
        map.put(5200, 16*2);
        map.put(8888, 9*2-1);
        map.put(11111, 3*2);
        map.put(33333, 2*2-1);
        map.put(52000, 1*2);
        map.put(66666, 1);
        return map;
    }
    /**
     * D奖池 投入50w钻以上
     */
    private static LinkedHashMap<Integer, Integer> getGiftCoinfigD() {
        LinkedHashMap<Integer, Integer> map = new LinkedHashMap<>();
        map.put(1, 39500);
        map.put(10, 800);
        map.put(30, 500);
        map.put(52, 100);
        map.put(199, 100);
        map.put(520, 80);
        map.put(999, 70);
        map.put(1111, 60);
        map.put(1999, 55);
        map.put(3344, 37);
        map.put(5200, 20);
        map.put(8888, 10);
        map.put(11111, 3);
        map.put(33333, 2);
        map.put(52000, 1);
        map.put(66666, 1);
        return map;
    }

    /**
     * D奖池 投入200w钻以上
     */
    private static LinkedHashMap<Integer, Integer> getGiftCoinfigE() {
        LinkedHashMap<Integer, Integer> map = new LinkedHashMap<>();
        map.put(1, 122700);
        map.put(10, 2400);
        map.put(30, 1500);
        map.put(52, 300);
        map.put(199, 300);
        map.put(520, 240);
        map.put(999, 210);
        map.put(1111, 180);
        map.put(1999, 165);
        map.put(3344, 111);
        map.put(5200, 60);
        map.put(8888, 30);
        map.put(11111, 9);
        map.put(33333, 6);
        map.put(52000, 3);
        map.put(66666, 3);
        map.put(88888, 1);
        return map;
    }

    static void testLuck2(Map<Integer, Integer> map){
        Map<Integer, Integer> out = new HashMap<>();
        for (int j = 0; j < 1; j++) {
            for (int i = 0; i < 100000; i++) {
                int luck = LuckyUtil.luckRandom( map, 1, 10000000);
                if (out.containsKey(luck)) {
                    out.put(luck, out.get(luck) + 1);
                } else {
                    out.put(luck, 1);
                }
            }
        }
        LuckyUtil.printConfig(out, price);
    }

    public static void main(String[] args) {
        System.out.println("-------A-------");
        LuckyUtil.printConfig(getGiftCoinfigA(), price);
        System.out.println("-------B-------");
        LuckyUtil.printConfig(getGiftCoinfigB(), price);
        System.out.println("-------C-------");
        LuckyUtil.printConfig(getGiftCoinfigC(), price);
        System.out.println("-------D-------");
        LuckyUtil.printConfig(getGiftCoinfigD(), price);
        System.out.println("-------E-------");
        LuckyUtil.printConfig(getGiftCoinfigE(), price);
        System.out.println("--------------");
//        testLuck2(getGiftCoinfigA());
//        System.out.println("--------------");

        LuckyUtil102 luckyUtil = new LuckyUtil102();
        Map <Integer, Integer> result = new LinkedHashMap<>();
        List<UserLuck> userLucks = new ArrayList<>();
        for (int i = 0; i < 2000; i++) {
            UserLuck user = new UserLuck();
            user.id=i;
            while (true) {
                luckyUtil.luckTest(user, result);
//                if (user.totalPay>=1200000 || (user.totalIncome*0.85d-user.totalPay>0 && user.totalPay>500000)) {
                if (user.totalPay>=3000000 || (user.totalIncome*0.85d-user.totalPay>0)) {
//                if (user.totalPay>=1500000) {
                    double rate  = BigDecimal.valueOf(user.totalIncome).divide(BigDecimal.valueOf(user.totalPay), 4, BigDecimal.ROUND_HALF_UP).doubleValue();
                    System.out.println(i+": 投入："+user.totalPay+" 产出:"+user.totalIncome +"  爆率:"+rate+ " 实际盈利："+(int)(user.totalIncome*0.85d-user.totalPay));
                    break;
                }
            }
            userLucks.add(user);
        }

        LuckyUtil.printConfig(result, price);

        LuckyUtil.tjUser(userLucks);

        System.out.println("------------系统爆率------------");
        System.out.println("A 系统投入:"+luckyUtil.poolA.allPay+" 产出:"+luckyUtil.poolA.allIncome+" 总爆率:"+ ((double)luckyUtil.poolA.allIncome/luckyUtil.poolA.allPay)+" 奖池剩余："+luckyUtil.poolA.giftCount+" 剩余爆率:"+((double)luckyUtil.poolA.pool/price/luckyUtil.poolA.giftCount));
        System.out.println("B 系统投入:"+luckyUtil.poolB.allPay+" 产出:"+luckyUtil.poolB.allIncome+" 总爆率:"+ ((double)luckyUtil.poolB.allIncome/luckyUtil.poolB.allPay)+" 奖池剩余："+luckyUtil.poolB.giftCount+" 剩余爆率:"+((double)luckyUtil.poolB.pool/price/luckyUtil.poolB.giftCount));
        System.out.println("C 系统投入:"+luckyUtil.poolC.allPay+" 产出:"+luckyUtil.poolC.allIncome+" 总爆率:"+ ((double)luckyUtil.poolC.allIncome/luckyUtil.poolC.allPay)+" 奖池剩余："+luckyUtil.poolC.giftCount+" 剩余爆率:"+((double)luckyUtil.poolC.pool/price/luckyUtil.poolC.giftCount));
        System.out.println("D 系统投入:"+luckyUtil.poolD.allPay+" 产出:"+luckyUtil.poolD.allIncome+" 总爆率:"+ ((double)luckyUtil.poolD.allIncome/luckyUtil.poolD.allPay)+" 奖池剩余："+luckyUtil.poolD.giftCount+" 剩余爆率:"+((double)luckyUtil.poolD.pool/price/luckyUtil.poolD.giftCount));
        System.out.println("E 系统投入:"+luckyUtil.poolE.allPay+" 产出:"+luckyUtil.poolE.allIncome+" 总爆率:"+ ((double)luckyUtil.poolE.allIncome/luckyUtil.poolE.allPay)+" 奖池剩余："+luckyUtil.poolE.giftCount+" 剩余爆率:"+((double)luckyUtil.poolE.pool/price/luckyUtil.poolE.giftCount));
        System.out.println("总 系统投入:"+(luckyUtil.poolA.allPay+luckyUtil.poolB.allPay+luckyUtil.poolC.allPay+luckyUtil.poolD.allPay)+
                " 产出:"+(luckyUtil.poolA.allIncome+luckyUtil.poolB.allIncome+luckyUtil.poolC.allIncome+luckyUtil.poolD.allIncome)+
                " 总爆率:"+ ((double)(luckyUtil.poolA.allIncome+luckyUtil.poolB.allIncome+luckyUtil.poolC.allIncome+luckyUtil.poolD.allIncome)/(luckyUtil.poolA.allPay+luckyUtil.poolB.allPay+luckyUtil.poolC.allPay+luckyUtil.poolD.allPay)));
    }
}